/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.openide.nodes; import java.lang.ref.WeakReference; import java.beans.beancontext.*; import java.beans.IntrospectionException; import java.util.Map; import java.util.HashMap; import java.util.Arrays; /** Class that represents bean children of a JavaBeans context. * It listens on the bean context changes and creates nodes for * child beans. By default {@link BeanNode}s are created for all * child beans, but this behaviour can be changed by * providing a different factory to the constructor. * * @author Jaroslav Tulach */ public class BeanChildren extends Children.Map { /** default factory for creation of children */ private static final Factory DEFAULT_FACTORY = new BeanFactory (); /** bean context to work on */ private BeanContext bean; /** factory for creation of subnodes */ private Factory factory; /** context listener */ private ContextL contextL; /** Create {@link BeanNode} children based on a Bean context. * @param bean the context */ public BeanChildren(BeanContext bean) { this (bean, DEFAULT_FACTORY); } /** Create children based on a Bean context. * @param bean the context * @param factory a factory to use for creation of child nodes */ public BeanChildren (BeanContext bean, Factory factory) { this.bean = bean; this.factory = factory; } /** Helper method. Converts array of beans to map from * the (beans, Nodes) * @param array array of beans * @return map (Object, Node) */ private java.util.Map createMap (Object[] array) { HashMap map = new HashMap (); for (int i = 0; i < array.length; i++) { try { map.put (array[i], factory.createNode (array[i])); } catch (IntrospectionException ex) { // ignore the exception } } return map; } /* Initializes children. * * @return map (Object, Node) */ protected java.util.Map initMap () { // attaches a listener to the bean contextL = new ContextL (this); bean.addBeanContextMembershipListener (contextL); // test if there is a child //if (bean.size () == 0) return null; return createMap (bean.toArray ()); } /** Cease listening to changes in the bean context membership. */ protected void finalize () { if (contextL != null) bean.removeBeanContextMembershipListener (contextL); } /** Controls which nodes * are created for a child bean. * @see BeanChildren#BeanChildren(BeanContext, BeanChildren.Factory) */ public static interface Factory { /** Create a node for a child bean. * @param bean the bean * @return the node for the bean * @exception IntrospectionException if the node cannot be created */ public Node createNode (Object bean) throws IntrospectionException; } /** Default factory. Creates BeanNode for each bean */ private static class BeanFactory extends Object implements Factory { /** @return bean node */ public Node createNode (Object bean) throws IntrospectionException { return new BeanNode (bean); } } /** Context listener. */ private static final class ContextL implements BeanContextMembershipListener { /** weak reference to the BeanChildren object */ private WeakReference ref; /** Constructor */ ContextL (BeanChildren bc) { ref = new WeakReference (bc); } /** Listener method that is called when a bean is added to * the bean context. * @param bcme event describing the action */ public void childrenAdded (BeanContextMembershipEvent bcme) { BeanChildren bc = (BeanChildren)ref.get (); if (bc != null) { bc.putAll (bc.createMap (bcme.toArray ())); } } /** Listener method that is called when a bean is removed to * the bean context. * @param bcme event describing the action */ public void childrenRemoved (BeanContextMembershipEvent bcme) { BeanChildren bc = (BeanChildren)ref.get (); if (bc != null) { bc.removeAll (Arrays.asList (bcme.toArray ())); } } } } /* * Log * 7 Gandalf 1.6 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 6 Gandalf 1.5 8/30/99 Jesse Glick Fixed * NullPointerException from finalizing uninitialized BeanChildren; see EAP * 27.8.99 Bryan Vold. * 5 Gandalf 1.4 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 4 Gandalf 1.3 4/30/99 Ales Novak initMap does not return * null * 3 Gandalf 1.2 3/18/99 Jesse Glick [JavaDoc] * 2 Gandalf 1.1 3/16/99 Jesse Glick [JavaDoc] * 1 Gandalf 1.0 1/5/99 Ian Formanek * $ */